package com.gitee.wsl.common.chart.render.foreground.info

import android.graphics.*
import com.gitee.wsl.common.chart.ChartEnum
import com.gitee.wsl.android.ui.ext.type.drawLine
import com.gitee.wsl.common.ui.draw.type.LineSpacingStyle
import com.gitee.wsl.android.ui.ext.type.textHeight
import com.gitee.wsl.android.ui.ext.type.textWidth
import com.gitee.wsl.ext.string.empty


/**
 * @ClassName AnchorDataPoint
 * @Description 数据批注基类
 * @author XiongChuanLiang<br/>(xcl_168@aliyun.com)
 *
 */
class Anchor() {

    var dataSeriesID = -1 //

    var dataChildID = -1 //Points
    
    var anchorStyle = ChartEnum.AnchorStyle.RECT
    var anchor = String.empty()
    var anchorTextSize = 22f
    var anchorTextColor = Color.BLUE

    var bgColor = Color.BLACK
    var alpha = 100
    var areaStyle = ChartEnum.DataAreaStyle.STROKE

    var radius = 30f
    var roundRaidus = 15f

    var lineWidth = -1f
    //private ChartEnum.LineStyle  mLineStyle = ChartEnum.LineStyle.SOLID;

    //private ChartEnum.LineStyle  mLineStyle = ChartEnum.LineStyle.SOLID;
     var capRectW = 20f
     var capRectH = 10f
    /**
     * 当风格为CAPRECT时，设置Rect的高度
     */
     val capRectHeight = 30f

    //线的风格(点或线之类)
     var lineSpacingStyle = LineSpacingStyle.Solid

    constructor( dataSeriesID:Int, dataChildID:Int, anchorStyle:ChartEnum.AnchorStyle):this(){
        this.dataSeriesID=dataSeriesID
        this.dataChildID=dataChildID
        this.anchorStyle=anchorStyle
    }

    /**
     * 当风格为CAPRECT时，可用此函数来设置三角形的宽/高
     * @param width  三角形的宽
     * @param height 三角形的高
     */
    fun setCapRectAngleWH(capWidth: Float, capHeight: Float) {
        capRectW = capWidth
        capRectH = capHeight
    }

     var rect: RectF? = null

     val textPaint: Paint by lazy {
         Paint(Paint.ANTI_ALIAS_FLAG).apply {
             textAlign = Paint.Align.CENTER
         }
     }
    
     val bgPaint: Paint by lazy {
         Paint(Paint.ANTI_ALIAS_FLAG).apply {
             strokeWidth = 2f
         }
     }

    fun renderAnchor(
        canvas: Canvas,
        cx: Float, cy: Float, cradius: Float,
        left: Float, top: Float, right: Float, bottom: Float
    ) {
        
        val radius = radius
        when (areaStyle) {
            ChartEnum.DataAreaStyle.FILL -> bgPaint.style = Paint.Style.FILL
            ChartEnum.DataAreaStyle.STROKE -> bgPaint.style = Paint.Style.STROKE
        }
        bgPaint.color = bgColor
        val width: Float = bgPaint.strokeWidth
        if (lineWidth > -1) {
            bgPaint.strokeWidth = lineWidth
        }
        when (anchorStyle) {
            ChartEnum.AnchorStyle.CAPRECT,
            ChartEnum.AnchorStyle.CAPROUNDRECT,
            ChartEnum.AnchorStyle.ROUNDRECT ->
                     drawRoundRect(canvas, cx, cy, radius)
            else -> {
                when (anchorStyle) {
                    ChartEnum.AnchorStyle.RECT ->
                        drawRect(canvas, bgPaint, radius, cx, cy)
                    ChartEnum.AnchorStyle.CIRCLE ->
                        canvas.drawCircle(cx, cy, radius, bgPaint)
                    ChartEnum.AnchorStyle.VLINE ->
                       canvas.drawLine(lineSpacingStyle, cx, top, cx, bottom, bgPaint)
                    ChartEnum.AnchorStyle.HLINE ->
                        canvas.drawLine(lineSpacingStyle, left, cy, right, cy, bgPaint)
                    ChartEnum.AnchorStyle.TOBOTTOM ->
                        canvas.drawLine(lineSpacingStyle, cx, cy + cradius, cx, bottom, bgPaint)
                    ChartEnum.AnchorStyle.TOTOP ->
                        canvas.drawLine(lineSpacingStyle, cx, cy - cradius, cx, top, bgPaint)
                    ChartEnum.AnchorStyle.TOLEFT ->
                        canvas.drawLine(lineSpacingStyle, cx - cradius, cy, left, cy, bgPaint)
                    ChartEnum.AnchorStyle.TORIGHT -> canvas.drawLine(lineSpacingStyle, cx + cradius, cy, right, cy, bgPaint)
                    else -> {}
                }
                if (anchor.trim { it <= ' ' } !== "") {
                    textPaint.color = anchorTextColor
                    textPaint.textSize = anchorTextSize
                    canvas.drawText(anchor, cx, cy, textPaint)
                }
            }
        }
        bgPaint.strokeWidth = width
    }

    private fun drawRoundRect(
        canvas: Canvas,
        cirX: Float, cirY: Float, radius: Float
    ) {
        val angleW = capRectW / 2 //20.f;
        val angleH = capRectH //10.f;
        var fontH = capRectHeight // angleH ; // + 5.f;
        var extW = angleW + radius
        if (radius.compareTo(angleW) == -1 || radius.compareTo(angleW) == 0
        ) {
            extW = angleW + 30f
        }
        val anchor = anchor.trim { it <= ' ' }
        if (this.anchor !== "") {

            val textHeight = textPaint.textHeight + 30f
            if (textHeight.compareTo(fontH) == 1) fontH = textHeight
            val textWidth = textPaint.textWidth(anchor)
            if (textWidth.compareTo(extW) == 1) extW = textWidth
        }
        when (anchorStyle) {
            ChartEnum.AnchorStyle.CAPRECT ->
                drawCapRect(canvas, cirX, cirY, radius, angleW, angleH, fontH, extW)

            ChartEnum.AnchorStyle.CAPROUNDRECT ->
                drawCapRound(canvas, cirX, cirY, radius, angleW, angleH, fontH, extW)

            ChartEnum.AnchorStyle.ROUNDRECT ->
                drawRound(canvas, cirX, cirY, radius, angleW, angleH, fontH, extW)
            else -> {}
        }
        if (this.anchor !== "") {
            textPaint.color = anchorTextColor
            textPaint.textSize = anchorTextSize
            canvas.drawText(anchor, cirX, cirY - angleH - fontH / 3, textPaint)
        }
    }

    private fun drawCapRound(
        canvas: Canvas,
        cirX: Float, cirY: Float, radius: Float,
        angleW: Float, angleH: Float, fontH: Float, extW: Float
    ) {
        //round Rect这种强制bgPaint为fill
        bgPaint.style = Paint.Style.FILL
        drawRound(canvas,  cirX, cirY, radius, angleW, angleH, fontH, extW)
        drawCap(canvas,  cirX, cirY, radius, angleW, angleH, fontH, extW)
    }

    private fun drawCapRect(
        canvas: Canvas,
        cirX: Float, cirY: Float, radius: Float,
        angleW: Float, angleH: Float, fontH: Float, extW: Float
    ) {
        val path = Path()
        path.moveTo(cirX, cirY)
        path.lineTo(cirX - angleW, cirY - angleH)
        path.lineTo(cirX - extW, cirY - angleH)
        path.lineTo(cirX - extW, cirY - angleH - fontH)
        path.lineTo(cirX + extW, cirY - angleH - fontH)
        path.lineTo(cirX + extW, cirY - angleH)
        path.lineTo(cirX + angleW, cirY - angleH)
        path.lineTo(cirX, cirY)
        path.close()
        canvas.drawPath(path,bgPaint)
        path.reset()
    }

    private fun drawRound(
        canvas: Canvas,
        cirX: Float, cirY: Float, radius: Float,
        angleW: Float, angleH: Float, fontH: Float, extW: Float
    ) {
        if (null == rect) rect = RectF()
        rect!!.left = cirX - extW
        rect!!.top = cirY - angleH - fontH
        rect!!.right = cirX + extW
        rect!!.bottom = cirY - angleH
        bgPaint.style = Paint.Style.FILL
        canvas.drawRoundRect(
            rect!!, roundRaidus,
            roundRaidus, bgPaint
        )
        rect!!.setEmpty()
    }

    private fun drawCap(
        canvas: Canvas,
        cirX: Float, cirY: Float, radius: Float,
        angleW: Float, angleH: Float, fontH: Float, extW: Float
    ) {
        val path = Path()
        path.moveTo(cirX, cirY)
        path.lineTo(cirX - angleW, cirY - angleH)
        path.lineTo(cirX + angleW, cirY - angleH)
        path.close()
        canvas.drawPath(path, bgPaint)
        path.reset()
    }

    private fun drawRect(
        canvas: Canvas, paint: Paint,
        radius: Float, cirX: Float, cirY: Float
    ) {
        if (null == rect) rect = RectF()
        rect!!.left = cirX - radius
        rect!!.top = cirY - radius
        rect!!.right = cirX + radius
        rect!!.bottom = cirY + radius
        canvas.drawRect(rect!!, bgPaint)
        rect!!.setEmpty()
    }
    
}